#include "cube.h"

Cube::Cube() : SolidObject(), X(), Y(), Z(), size()
{

}

Cube::~Cube()
{

}

Cube::Cube(const Cube &cube) : SolidObject(cube), X(cube.X), Y(cube.Y), Z(cube.Z), size(cube.size)
{

}

Cube& Cube::operator=(const Cube &cube)
{
    ((SolidObject*)this)->operator=(cube);
    X    = cube.X;
    Y    = cube.Y;
    Z    = cube.Z;
    size = cube.size;
    return (*this);
}

Cube::Cube(const Point3D &origin, const Color &color, const Vector3D &_x, const Vector3D &_y, const Vector3D &_z, const double &_size) :
   SolidObject(origin,color), X(_x), Y(_y), Z(_z), size(_size)
{

}


inline bool Cube::isInside(const Point3D &point) const
{
    Vector3D proj(point-(*this));
    if( proj.norm() > 0.0 )
    {
        return (((proj*X) < size)
            &&  ((proj*Y) < size)
            &&  ((proj*Z) < size) );
    }
    else
        return false;
}

inline bool Cube::isInside(Intersection &point) const
{
    Vector3D proj(point-(*this));
    if( proj.norm() > 0.0 )
    {
        return (((proj*X) < size)
            &&  ((proj*Y) < size)
            &&  ((proj*Z) < size) );
    }
    else
        return false;
}

void Cube::texturing(const Intersection &inter)
{

}


inline void Cube::intersectionX(const Ray &ray,Intersection &inter) const
{
    double a,b,c,k;
    Vector3D v(getX(),getY(),getZ());
    Vector3D vO(ray.getOrigin().getX(),ray.getOrigin().getY(),ray.getOrigin().getZ());
    a=X*v;
    b=X*vO;
    c=X*ray.getDirection();
    k=(a-b)/c;
    if( k > 0.0 )
    {
        inter.setDistance(k);
        inter.setPosition(ray.getOrigin()+ ray.getDirection()*k);
        if( isInside(inter) )
        {
            inter.setValid(true);
            inter.setObject((SolidObject*)this);
        }
    }
    else
        inter.setValid(false);
}

inline void Cube::intersectionY(const Ray &ray,Intersection &inter) const
{

}

inline void Cube::intersectionZ(const Ray &ray,Intersection &inter) const
{

}

void Cube::intersection(const Ray &ray,Intersection &inter) const
{
    Intersection inter2;
    if( ray.getDirection()*X < 0.0 )
    {
        if( ray.getDirection()*Y < 0.0 )
        {
            if( ray.getDirection()*Z < 0.0 )
            {
                //inter en Z, X ou Y
                intersectionX(ray,inter2);
                if( inter2.isValid() )
                    inter = inter2;
                else
                {
                    intersectionY(ray,inter2);
                    if( inter2.isValid() )
                        inter = inter2;
                    else
                    {
                        intersectionZ(ray,inter2);
                        if( inter2.isValid() )
                            inter = inter2;
                    }
                }

            }
            else
            {
                //inter en -Z, X ou Y

            }
        }
        else
        {
            if( ray.getDirection()*Z < 0.0 )
            {
                //inter en Z, X ou -Y

            }
            else
            {
                //inter en -Z, X ou -Y

            }
        }
    }
    else
    {
        if( ray.getDirection()*Y < 0.0 )
        {
            if( ray.getDirection()*Z < 0.0 )
            {
                //inter en Z, -X ou Y

            }
            else
            {
                //inter en -Z, -X ou Y

            }
        }
        else
        {
            if( ray.getDirection()*Z < 0.0 )
            {
                //inter en Z, -X ou -Y

            }
            else
            {
                //inter en -Z, -X ou -Y

            }
        }
    }
}

void Cube::getNormalVectorAt(const Point3D &inter, Vector3D &res) const
{

}
